package com.github.dgxwl.base.handler.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import com.github.dgxwl.base.entity.Column;
import com.github.dgxwl.base.entity.PrimaryKey;
import com.github.dgxwl.base.entity.Table;

public class CreateSQLHandler {

	public static Table getTableByCreateSQL(String tableSQL) {
		tableSQL = tableSQL.trim().replaceAll("\\r|\\n", "");
		String[] sqlParts = tableSQL.split("\\s");  //create table tableName...
		String tableName = sqlParts[2].replaceAll("\"|public|\\.|`", "");
		Table table = new Table();
		table.setTableName(tableName);
		
		int indexOfOpen = tableSQL.indexOf('(');
		if (indexOfOpen == -1) {
			throw new IllegalStateException("未解析到字段，请检查语句语法");
		}
		int indexOfClose = -1;
		Stack<Character> stack = new Stack<>();
		stack.push(tableSQL.charAt(indexOfOpen));
		for (int i = indexOfOpen + 1, length = tableSQL.length(); i < length; i++) {
			char charAt = tableSQL.charAt(i);
			if (charAt == '(') {
				stack.push(charAt);
				continue;
			}
			if (charAt == ')') {
				stack.pop();
			}
			if (stack.isEmpty()) {
				indexOfClose = i;
				break;
			}
		}
		if (indexOfClose == -1) {
			throw new IllegalStateException("未解析到字段，请检查语句语法");
		}
		
		String allColStr = tableSQL.substring(indexOfOpen + 1, indexOfClose).trim().replaceAll("\"|`", "");
		
		Map<String, String> colNameAndTypeMap = new HashMap<>();
		String[] colParts = allColStr.split("[\\s]*,[\\s]*");  //columns str
		for (String colStr : colParts) {
			char firstCh = colStr.charAt(0);
			if (!Character.isAlphabetic(firstCh)) {
				continue;
			}
			Column col = new Column();
			
			String[] split = colStr.split(" ");
			String colName = split[0];
			if (colName.equalsIgnoreCase("CONSTRAINT")) {  //是pgsql主键
				String part4 = split[4].replaceAll("\"|\\(|\\)", "");  //CONSTRAINT keyName PRIMARY KEY ("key_col")
				PrimaryKey pk = new PrimaryKey();
				pk.setPkName(part4);
				pk.setPkType(colNameAndTypeMap.get(part4));
				table.addPrimaryKey(pk);
				
				continue;
			}
			if (colName.equalsIgnoreCase("PRIMARY")) {  //是mysql主键
				String part2 = split[2].replaceAll("`|\\(|\\)", "");  //PRIMARY KEY (`key_col`)
				PrimaryKey pk = new PrimaryKey();
				pk.setPkName(part2);
				pk.setPkType(colNameAndTypeMap.get(part2));
				table.addPrimaryKey(pk);
				
				continue;
			}
			
			String colType = split[1];
			int idx = colType.indexOf('(');
			if (idx != -1) {
				colType = colType.substring(0, idx);
			}
			colType = colType.toUpperCase();
			col.setColumnName(colName);
			col.setType(colType);
			
			colNameAndTypeMap.put(colName, colType);
			table.addColumn(col);
			
			if (split.length > 2 && split[2].equalsIgnoreCase("PRIMARY")) {
				PrimaryKey pk = new PrimaryKey();
				pk.setPkName(colName);
				pk.setPkType(colType);
				table.addPrimaryKey(pk);
			}
		}
		table.setColumnNameAndType(colNameAndTypeMap);
		
		return table;
	}

	public static Table getTableByCreateSQL(String mainTableSQL, List<String> slaveTableSQLs) {
		Table mainTable = getTableByCreateSQL(mainTableSQL);
		List<Table> slaves = new ArrayList<>(slaveTableSQLs.size());
		for (String sql : slaveTableSQLs) {
			Table slave = getTableByCreateSQL(sql);
			slaves.add(slave);
		}
		mainTable.setSlaves(slaves);
		return mainTable;
	}
}
